package instgram

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-resty/resty/v2"
	"net/http"
	"net/url"
	"sieve_engine/execute"
	"sieve_engine/lib/config"
	"sieve_engine/lib/log"
	"sieve_engine/task"
	"sieve_engine/utils"
	"time"
)

const (
	instagramApi = "https://i.instagram.com/api/v1/users/lookup/"
)

type instagramExecutor struct {
	*execute.DefaultExecutor
	execute.DefaultNetWorkConfig
}

var (
	insExecutor execute.TaskExecutorInterface = &instagramExecutor{
		DefaultExecutor: &execute.DefaultExecutor{
			Debug:                *config.Bool("sieve.ins.debug", true, "debug"),
			PrintMore:            *config.Bool("sieve.ins.print_more", true, "print more"),
			ProxyEnable:          *config.Bool("sieve.ins.proxy.enable", true, "proxy enable"),
			ProxyDebug:           *config.Bool("sieve.ins.proxy.debug", true, "proxy debug"),
			NetworkErrRetryCount: *config.Int("sieve.ins.proxy.retry_count_if_network_error", -1, "retry count if network error"),
			DefaultResultCache:   execute.NewDefaultResultCache(),
		},
	}
)

func init() {

	execute.Register("ins", insExecutor)
}

func (s *instagramExecutor) Execute(params execute.TaskExecutorParams, taskProgress *task.Result) error {

	return s.DefaultExecutor.Execute(params, taskProgress, s.getApi2)
}

// func (s *instagramExecutor) getApi(phone string, taskInfo task.Info, roundTripper http.RoundTripper, reuseProxy bool) (http.RoundTripper, bool, *url.URL, error) {
//
//	if s.Debug {
//		return nil, true, nil, nil
//	}
//
//	start := time.Now()
//	dataBean := manager.NewInsRequestData(phone, taskInfo.AreaCode)
//	bytes, _ := json.Marshal(dataBean)
//	body := "signed_body=SIGNATURE." + string(bytes)
//	bodyReader := strings.NewReader(body)
//
//	req, err := http.NewRequest("POST", instagramApi, bodyReader)
//	if err != nil {
//		return nil, false, nil, err
//	}
//
//	s.buildHeaders(req.Header)
//
//	req.Close = true
//
//	var proxyURL *url.URL
//	httpClient := &http.Client{Timeout: time.Second * 8}
//	if !reuseProxy {
//		/* 如果不带用代理复用策略，那么就重新获取代理 */
//		roundTripper, proxyURL = manager.SetDefaultTransport("", s.GetNetWorkConfig())
//	}
//
//	httpClient.Transport = roundTripper
//	response, err := httpClient.Do(req)
//	if err != nil {
//		return nil, false, nil, err
//	}
//
//	log.Info(fmt.Sprintf("请求接口耗时：%v", time.Since(start).String()))
//	if response.StatusCode != http.StatusOK {
//		return nil, false, nil, errors.New(fmt.Sprintf("http failed,code:%d", response.StatusCode))
//	}
//	bytes, err = io.ReadAll(response.Body)
//	if err != nil {
//		return nil, false, nil, errors.New(fmt.Sprintf("ReadAll failed,%s", err.Error()))
//	}
//
//	if len(bytes) == 0 {
//		return nil, false, nil, manager.RequestErrorNetError
//	}
//
//	if response.StatusCode == 200 {
//		resultBean := new(manager.InsResponseData)
//		err := json.Unmarshal(bytes, resultBean)
//		if err != nil {
//			return nil, false, nil, nil
//		}
//		if resultBean.Status == "ok" {
//			if resultBean.HasValidPhone {
//				return nil, true, nil, nil
//			} else {
//				return nil, false, nil, nil
//			}
//		}
//	}
//
//	return nil, false, proxyURL, manager.RequestErrorNetError
// }

func (s *instagramExecutor) getApi2(phone string, params execute.TaskExecutorParams, roundTripper http.RoundTripper, reuseProxy bool) (http.RoundTripper, bool, *url.URL, error) {

	if s.Debug {
		return nil, true, nil, nil
	}

	var (
		proxyUrl *url.URL
		client   = resty.New()
	)

	// client.SetCloseConnection(true)
	if !reuseProxy {
		/* 如果不带用代理复用策略，那么就重新获取代理 */
		roundTripper, proxyUrl = execute.SetDefaultTransport("", s.GetNetWorkConfig())
	}

	var (
		start    = time.Now()
		dataBean = NewInsRequestData(phone, params.TaskInfo.AreaCode)
		bytes, _ = json.Marshal(dataBean)
		body     = "signed_body=SIGNATURE." + string(bytes)
	)

	s.buildHeaders(client.Header)
	client.SetTransport(roundTripper).SetTimeout(s.GetNetWorkConfig().HttpConfig.Timeout)
	resp, err := client.SetDebug(s.ProxyDebug).R().SetBody(body).Post(instagramApi)
	if err != nil {
		return roundTripper, false, proxyUrl, err
	}
	if s.PrintMore {
		log.Info(fmt.Sprintf("请求接口耗时：%v", time.Since(start).String()))
	}

	if resp.StatusCode() != http.StatusOK {
		if resp.StatusCode() == http.StatusNotFound {
			return roundTripper, false, proxyUrl, nil
		}
		if resp.StatusCode() == http.StatusTooManyRequests {
			return roundTripper, false, proxyUrl, execute.RequestErrorForbidden
		}
		return roundTripper, false, proxyUrl, errors.New(fmt.Sprintf("http failed,code:%d", resp.StatusCode()))
	}

	resultBean := new(InsResponseData)
	err = json.Unmarshal(resp.Body(), resultBean)
	if err != nil {
		return nil, false, nil, nil
	}
	if resultBean.Status == "ok" {
		if resultBean.HasValidPhone {
			return roundTripper, true, proxyUrl, nil
		} else {
			return roundTripper, false, proxyUrl, nil
		}
	}

	return roundTripper, false, proxyUrl, execute.RequestErrorNetError
}

func (s *instagramExecutor) buildHeaders(header http.Header) {
	header.Add("X-IG-App-Locale", "zh_CN")
	header.Add("X-IG-Device-Locale", "en_US")
	header.Add("X-IG-Mapped-Locale", "zh_CN")
	// header.Add("X-Pigeon-Session-Id","bab4f3ab-367a-4650-932a-5f00c2b2eb12")
	header.Add("X-Pigeon-Rawclienttime", utils.NowTime14BitWithDot())
	header.Add("X-IG-Bandwidth-Speed-KBPS", "-1.000")
	header.Add("x-ig-bandwidth-totalbytes-b", "0")
	header.Add("x-ig-bandwidth-totaltime-ms", "0")
	// header.Add("X-Bloks-Version-Id","e6bff5d5ad51ac25d872c2a0dd1b96d7eb4ba6021694601d6e2f803c7a81be6e")
	header.Add("X-IG-WWW-Claim", "0")
	header.Add("x-bloks-is-layout-rtl", "false")
	header.Add("x-bloks-is-panorama-enabled", "true")
	// header.Add("x-ig-device-id","c3d0ce4c-c663-4f15-bbe5-7b895488296f")
	// header.Add("x-ig-family-device-id","7e316521-3214-435e-992e-522ed304e59e")
	header.Add("X-IG-Android-ID", "android-ccd0ec1b97d99911")
	header.Add("X-IG-Timezone-Offset", "28800")
	header.Add("X-IG-Capabilities", "3brTvx0=")
	header.Add("X-IG-App-ID", "567067343352427")
	header.Add("User-Agent", "Instagram 188.0.0.35.124 Android (29/10; 320dpi 720x1368; BLU; G50 Plus; G0350WW; s9863a1h10; en_US; 292080186)")
	// header.Add("User-Agent", "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36")
	header.Add("Accept-Language", "zh-CN")
	header.Add("content-type", "application/x-www-form-urlencoded charset=UTF-8")
	// header.Add("X-MID","YnSZFgABAAFm-w55fDS-62fGFS8c")
	header.Add("IG-INTENDED-USER-ID", "0")

	// header.Add("Connection", "close")
}
